using System.IO;
using System.Windows;

namespace LicenseApp.Client;

/// <summary>
/// 授权集成助手 - 提供一键式集成方案
/// </summary>
public static class LicenseHelper
{
    /// <summary>
    /// 一键式授权检查和初始化
    /// </summary>
    /// <param name="parentWindow">父窗口（可选）</param>
    /// <param name="autoStartMonitoring">是否自动启动监控</param>
    /// <param name="onStatusChanged">状态变化回调（可选）</param>
    /// <param name="showErrorDialog">是否显示错误提示对话框</param>
    /// <returns>初始化结果</returns>
    public static LicenseInitResult InitializeLicense(
        Window? parentWindow = null,
        bool autoStartMonitoring = true,
        LicenseStatusCallback? onStatusChanged = null,
        bool showErrorDialog = true)
    {
        var result = new LicenseInitResult();

        try
        {
            // 1. 检查公钥文件
            var publicKeyResult = CheckPublicKey();
            if (!publicKeyResult.Success)
            {
                result.Success = false;
                result.Message = publicKeyResult.Message;

                // 根据参数决定是否显示非阻塞提醒
                if (showErrorDialog)
                {
                    ShowNonBlockingDialog(
                        "缺少公钥文件",
                        publicKeyResult.Message + "\n\n请联系供应商获取公钥文件。",
                        LicenseDialogType.Warning,
                        parentWindow);
                }

                return result;
            }

            // 2. 初始化授权系统
            if (!LicenseManager.Initialize(publicKeyResult.PublicKey!))
            {
                result.Success = false;
                result.Message = "授权系统初始化失败";

                // 根据参数决定是否显示非阻塞提醒
                if (showErrorDialog)
                {
                    ShowNonBlockingDialog(
                        "初始化失败",
                        "授权系统初始化失败，请检查公钥文件格式。",
                        LicenseDialogType.Error,
                        parentWindow);
                }

                return result;
            }

            // 3. 设置通知器
            LicenseManager.SetNotifier(new CustomWindowNotifier());

            // 4. 检查授权文件
            var licenseResult = CheckLicense();
            bool hasLicenseError = !licenseResult.Success;

            if (hasLicenseError)
            {
                result.Success = false;
                result.Message = licenseResult.Message;
                result.NeedsLicenseRegistration = true;

                // 不直接弹出对话框，继续初始化流程
                // 授权文件缺失或损坏，类似于过期等其他验证失败情况
            }

            // 5. 验证授权信息（即使授权文件检查失败也要尝试验证）
            var validationResult = ValidateLicense();
            bool hasValidationError = !validationResult.Success;

            // 如果之前没有授权文件错误，但验证失败了，更新结果
            if (!hasLicenseError && hasValidationError)
            {
                result.Success = false;
                result.Message = validationResult.Message;

                // 🎯 根据错误类型决定是否需要重新注册和给出不同建议
                string suggestion = GetSuggestionForValidationError(validationResult.Message);
                bool needsRegistration = !IsTimeRelatedError(validationResult.Message);

                result.NeedsLicenseRegistration = needsRegistration;
            }

            // 如果有任何授权相关的错误（文件错误或验证错误），根据参数决定是否显示提示
            if ((hasLicenseError || hasValidationError) && showErrorDialog)
            {
                string errorMessage = hasLicenseError ? licenseResult.Message : validationResult.Message;
                string suggestion = GetSuggestionForValidationError(errorMessage);

                ShowNonBlockingDialog(
                    "授权验证失败",
                    errorMessage + "\n\n" + suggestion,
                    LicenseDialogType.Warning,
                    parentWindow);
            }

            // 6. 启动监控（如果需要）- 即使验证失败也要启动，以便持续监控状态变化
            if (autoStartMonitoring)
            {
                var monitoringResult = StartMonitoring(onStatusChanged);
                if (!monitoringResult.Success)
                {
                    // 监控启动失败不影响主流程，只记录警告
                    result.Warnings.Add(monitoringResult.Message);
                }
            }

            // 7. 检查授权状态（无论是否有错误都要检查）
            var status = LicenseManager.GetCurrentStatus();
            result.LicenseStatus = status;

            // 根据状态显示相应提醒（仅在没有错误时显示，避免重复提醒）
            if (!hasLicenseError && !hasValidationError && showErrorDialog)
            {
                HandleLicenseStatus(status, parentWindow);
            }

            // 初始化流程完成（即使授权验证失败，初始化流程本身也是成功的）
            // result.Success 在前面已经根据授权状态设置了，这里不再修改

            // 设置最终的初始化消息
            if (!hasLicenseError && !hasValidationError)
            {
                result.Message = "授权系统初始化成功";
            }
            // 如果有授权错误，消息已经在前面设置了，这里不覆盖
            
            return result;
        }
        catch (Exception ex)
        {
            result.Success = false;
            result.Message = $"初始化过程中发生异常: {ex.Message}";
            
            ShowNonBlockingDialog(
                "系统异常",
                result.Message,
                LicenseDialogType.Error,
                parentWindow);
            
            return result;
        }
    }

    /// <summary>
    /// 检查公钥文件
    /// </summary>
    private static CheckResult CheckPublicKey()
    {
        try
        {
            // 应用程序路径获取 - 按要求实现
            string assemblyFilePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
            string assemblyDirPath = System.IO.Path.GetDirectoryName(assemblyFilePath) ?? "";
            string publicKeyPath = System.IO.Path.Combine(assemblyDirPath, "public.xml");

            if (!File.Exists(publicKeyPath))
            {
                return new CheckResult
                {
                    Success = false,
                    Message = "未找到公钥文件，请联系供应商获取"
                };
            }

            var publicKeyContent = File.ReadAllText(publicKeyPath);
            
            if (string.IsNullOrWhiteSpace(publicKeyContent) ||
                !publicKeyContent.Contains("<RSAKeyValue>"))
            {
                return new CheckResult
                {
                    Success = false,
                    Message = "公钥文件格式不正确"
                };
            }

            return new CheckResult
            {
                Success = true,
                Message = "公钥文件检查通过",
                PublicKey = publicKeyContent
            };
        }
        catch (Exception ex)
        {
            return new CheckResult
            {
                Success = false,
                Message = $"检查公钥文件时发生错误: {ex.Message}"
            };
        }
    }

    /// <summary>
    /// 检查授权文件
    /// </summary>
    private static CheckResult CheckLicense()
    {
        try
        {
            // 应用程序路径获取 - 按要求实现
            string assemblyFilePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
            string assemblyDirPath = System.IO.Path.GetDirectoryName(assemblyFilePath) ?? "";
            string licenseFilePath = System.IO.Path.Combine(assemblyDirPath, "System.ZhyLsHK.dll");

            if (!File.Exists(licenseFilePath))
            {
                return new CheckResult
                {
                    Success = false,
                    Message = "未找到授权文件，需要注册授权码"
                };
            }

            var licenseContent = File.ReadAllText(licenseFilePath);
            
            if (string.IsNullOrWhiteSpace(licenseContent))
            {
                return new CheckResult
                {
                    Success = false,
                    Message = "授权文件为空，需要重新注册授权码"
                };
            }

            return new CheckResult
            {
                Success = true,
                Message = "授权文件检查通过"
            };
        }
        catch (Exception ex)
        {
            return new CheckResult
            {
                Success = false,
                Message = $"检查授权文件时发生错误: {ex.Message}"
            };
        }
    }

    /// <summary>
    /// 验证授权信息
    /// </summary>
    private static CheckResult ValidateLicense()
    {
        try
        {
            if (!LicenseManager.IsLicenseValid())
            {
                // 🎯 使用详细的状态分析，而不是简单的null判断
                var statusInfo = LicenseManager.GetCurrentStatus();

                return new CheckResult
                {
                    Success = false,
                    Message = statusInfo.Message
                };
            }

            return new CheckResult
            {
                Success = true,
                Message = "授权验证通过"
            };
        }
        catch (Exception ex)
        {
            return new CheckResult
            {
                Success = false,
                Message = $"验证授权时发生错误: {ex.Message}"
            };
        }
    }

    /// <summary>
    /// 判断是否为时间相关的错误
    /// </summary>
    private static bool IsTimeRelatedError(string errorMessage)
    {
        return errorMessage.Contains("回拨时间") ||
               errorMessage.Contains("时间回拨") ||
               errorMessage.Contains("停滞") ||
               errorMessage.Contains("时间锁定") ||
               errorMessage.Contains("系统时间未超过");
    }

    /// <summary>
    /// 根据验证错误类型获取相应的建议
    /// </summary>
    private static string GetSuggestionForValidationError(string errorMessage)
    {
        if (IsTimeRelatedError(errorMessage))
        {
            return "请同步到正确的时间。";
        }
        else if (errorMessage.Contains("授权已过期"))
        {
            return "请联系供应商获取新的授权码。";
        }
        else if (errorMessage.Contains("格式错误") || errorMessage.Contains("签名验证失败"))
        {
            return "请确认授权码和公钥是配套的，或联系供应商重新获取。";
        }
        else if (errorMessage.Contains("未找到授权码文件"))
        {
            return "请注册有效的授权码。";
        }
        else if (errorMessage.Contains("尚未生效"))
        {
            return "请等待授权生效日期后再使用。";
        }
        else
        {
            return "请重新注册有效的授权码。";
        }
    }

    /// <summary>
    /// 启动监控
    /// </summary>
    private static CheckResult StartMonitoring(LicenseStatusCallback? callback)
    {
        try
        {
            bool success = LicenseManager.StartLicenseMonitoring(
                callback ?? DefaultStatusCallback,
                TimeSpan.FromMinutes(1));

            if (success)
            {
                return new CheckResult
                {
                    Success = true,
                    Message = "授权监控启动成功"
                };
            }
            else
            {
                return new CheckResult
                {
                    Success = false,
                    Message = "授权监控启动失败"
                };
            }
        }
        catch (Exception ex)
        {
            return new CheckResult
            {
                Success = false,
                Message = $"启动监控时发生错误: {ex.Message}"
            };
        }
    }

    /// <summary>
    /// 默认状态变化回调
    /// </summary>
    private static void DefaultStatusCallback(LicenseStatusInfo statusInfo)
    {
        // 默认只处理关键状态变化
        switch (statusInfo.Status)
        {
            case LicenseStatus.ExpiringSoon:
                LicenseManager.ShowNotification(
                    $"授权将在 {statusInfo.RemainingDays} 天后到期，请及时续期",
                    LicenseStatus.ExpiringSoon);
                break;

            case LicenseStatus.Expired:
                LicenseManager.ShowNotification(
                    "授权已过期，请联系供应商续期",
                    LicenseStatus.Expired);
                break;
        }
    }

    /// <summary>
    /// 处理授权状态
    /// </summary>
    private static void HandleLicenseStatus(LicenseStatusInfo status, Window? parentWindow)
    {
        switch (status.Status)
        {
            case LicenseStatus.Valid:
                // 正常状态，不需要特殊处理
                break;

            case LicenseStatus.ExpiringSoon:
                ShowNonBlockingDialog(
                    "授权即将到期",
                    $"您的授权将在 {status.RemainingDays} 天后到期，请及时联系供应商续期。",
                    LicenseDialogType.Warning,
                    parentWindow);
                break;

            case LicenseStatus.ExpiredGracePeriod:
                ShowNonBlockingDialog(
                    "授权已过期",
                    "您的授权已过期，但在宽限期内。请立即联系供应商续期。",
                    LicenseDialogType.Error,
                    parentWindow);
                break;

            case LicenseStatus.Expired:
                ShowNonBlockingDialog(
                    "授权已过期",
                    "您的授权已过期，某些功能可能受到限制。请联系供应商续期。",
                    LicenseDialogType.Error,
                    parentWindow);
                break;
        }
    }

    /// <summary>
    /// 显示非阻塞对话框
    /// </summary>
    public static void ShowNonBlockingDialog(
        string title,
        string message,
        LicenseDialogType type = LicenseDialogType.Information,
        Window? parentWindow = null)
    {
        try
        {
            var dialog = new NonBlockingDialog(title, message, type, parentWindow);
            dialog.Show(); // 非阻塞显示
        }
        catch
        {
            // 如果自定义对话框失败，回退到通知系统
            LicenseManager.ShowNotification(message, LicenseStatus.Valid);
        }
    }

    /// <summary>
    /// 显示授权注册对话框
    /// </summary>
    public static void ShowLicenseRegistrationDialog(Window? parentWindow, string message)
    {
        try
        {
            var dialog = new LicenseRegistrationDialog(message, parentWindow);
            dialog.Show(); // 非阻塞显示
        }
        catch
        {
            // 如果对话框失败，显示简单提醒
            ShowNonBlockingDialog(
                "需要注册授权",
                message + "\n\n请手动注册授权码。",
                LicenseDialogType.Warning,
                parentWindow);
        }
    }
}

/// <summary>
/// 授权初始化结果
/// </summary>
public class LicenseInitResult
{
    public bool Success { get; set; }
    public string Message { get; set; } = "";
    public bool NeedsLicenseRegistration { get; set; }
    public LicenseStatusInfo? LicenseStatus { get; set; }
    public List<string> Warnings { get; set; } = new();
}

/// <summary>
/// 检查结果
/// </summary>
internal class CheckResult
{
    public bool Success { get; set; }
    public string Message { get; set; } = "";
    public string? PublicKey { get; set; }
}

/// <summary>
/// 对话框类型
/// </summary>
public enum LicenseDialogType
{
    Information,
    Warning,
    Error
}
